package cn.iocoder.boot.flowabledemo.demos.web;

import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

import static com.mysql.cj.conf.PropertyKey.logger;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/process/v1")
public class ProcessControllerV1 {

    private final RepositoryService repositoryService;
    private final RuntimeService runtimeService;
    private final TaskService taskService;
    private final HistoryService historyService;
    // 在类中定义日志记录器
    private static final Logger logger = LoggerFactory.getLogger(ProcessControllerV1.class);

    /**
     * 部署流程模型到 Flowable 引擎。
     * <p>
     * 该方法将 BPMN 文件从类路径中加载并部署到 Flowable 引擎中。流程部署是使用 Flowable 引擎的第一步，
     * 它将 BPMN 文件转换为内部表示形式，以便后续启动流程实例和执行任务。
     *
     * @return 返回包含流程部署 ID 的响应
     */
    @PostMapping("/deploy")
    public ResponseEntity<Object> createProcessDef() {
        try {
            // 创建新的部署对象。部署是将 BPMN 文件等资源部署到 Flowable 引擎的过程
            Deployment deployment = repositoryService.createDeployment()
                    // 从类路径加载 BPMN 文件。这里 BPMN 文件位于 resources/process 目录下
                    .addClasspathResource("process/admin.bpmn20.xml")
                    // 设置部署名称，用于在 Flowable 引擎中标识这个部署
                    .name("2025年5月绩效")
                    // 执行部署操作
                    .deploy();

            // 通过流程部署id查询流程定义id
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                    // 设置查询条件为部署id
                    .deploymentId(deployment.getId())
                    // 执行查询并获取单个结果
                    .singleResult();

            // 返回成功的响应，包含部署 ID 和流程定义 ID
            return new ResponseEntity<>(BaseResponse.success(
                    // 构建一个包含部署 ID 和流程定义 ID 的 Map
                    //deploymentId:部署id、processDefinitionId:流程定义id
                    Map.of(
                            "deploymentId", deployment.getId(),
                            "processDefinitionId", processDefinition.getId()
                    )
            ), HttpStatus.OK);
        } catch (Exception e) {
            // 捕获异常并返回错误响应
            e.printStackTrace();
            return new ResponseEntity<>(BaseResponse.failure(1, "Failed: " + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    /**
     * 启动已部署的流程定义的流程实例。
     * <p>
     * 该方法通过指定的流程定义 ID 启动一个新的流程实例。流程实例代表流程的实际执行过程，
     * 它将按照 BPMN 文件中定义的流程步骤逐步执行。
     *
     * @return 返回包含流程实例 ID 的响应
     */
    @PostMapping("/start")
    public ResponseEntity<Object> startProcessDef() {
        // 指定要启动的流程定义 ID。这个 ID 可以通过部署流程后获取，或者通过查询流程定义列表获取
        String processId = "admin:2:0ff620f7-405d-11f0-981a-0a0027000005";

        // 使用 RuntimeService 启动流程实例。RuntimeService 是 Flowable 引擎中用于管理流程实例运行时状态的服务
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processId);

        // 返回成功的响应，包含流程实例 ID
        return new ResponseEntity<>(new BaseResponse<String>(0, "Success", processInstance.getId()), HttpStatus.OK);
    }

    /**
     * 启动流程.
     *
     * @return 流程key
     */
    @PostMapping("/start/{processId}")
    public ResponseEntity<Object> startProcessDef(@PathVariable String processId) {
        // 1.启动流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processId);
        // 2.维护该流程的分数变量
        runtimeService.setVariable(processInstance.getId(), "score", 100);
        //3.维护该流程的所属用户
        runtimeService.setVariable(processInstance.getId(),"ownerId", 88);
        // 4.返回流程实例对象id
        // 使用 BaseResponse 的 success 方法创建成功的响应
        return new ResponseEntity<>(BaseResponse.success(processInstance.getId()), HttpStatus.OK);
    }

    @PostMapping("/complete/agentUser/{agentUser}/score/{score}/processInstanceId/{processInstanceId}")
    public ResponseEntity<Object> completeTask(
            @PathVariable String agentUser,
            @PathVariable String score,
            @PathVariable String processInstanceId) {
        try {
            // 1. 查询指定用户的待办任务
            List<String> agentTaskIds = findUserAgentTasks(agentUser);

            // 检查是否找到待办任务
            if (agentTaskIds.isEmpty()) {
                // 如果没有找到任务，返回错误响应
                System.out.println(agentUser);
                return new ResponseEntity<>(BaseResponse.failure(1, "No tasks found for user: " + agentUser), HttpStatus.BAD_REQUEST);
            }

            // 2. 更新绩效流程变量
            runtimeService.setVariable(processInstanceId, "score", score);

            //    设置任务节点流程变量
            System.out.println(agentTaskIds);
            //将agentTaskIds中的任务id作为key，score作为value，设置到流程变量中
            for (String agentTaskId : agentTaskIds) {
                taskService.setVariableLocal(agentTaskId, "score2", score);
                System.out.println(agentTaskId);
            }

            // 3. 完成指定任务的审批
            // 假设我们完成列表中的第一个任务
            String agentTaskId = agentTaskIds.get(0);
            taskService.complete(agentTaskId);

            // 4. 返回响应
            return new ResponseEntity<>(BaseResponse.success(null), HttpStatus.OK);
        } catch (Exception e) {
            // 记录异常信息
            logger.error("Failed to complete task for user: {}, processInstanceId: {}", agentUser, processInstanceId, e);
            // 返回错误响应
            return new ResponseEntity<>(BaseResponse.failure(1, "Failed: " + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    /**
     * 完成指定用户的待办任务。
     * <p>
     * 该方法根据用户 ID 查询该用户的待办任务，并完成这些任务。完成任务是流程执行中的重要步骤，
     * 它将推进流程到下一个步骤，可能触发条件判断、网关选择等流程逻辑。
     *
     * @param agentUser 指定用户的用户名
     * @return 返回操作结果的响应
     */
    @PostMapping("/complete/{agentUser}")
    public ResponseEntity<Object> completeTask(@PathVariable String agentUser) {
        try {
            // 查询指定用户的待办任务 ID 列表
            List<String> agentTaskIds = findUserAgentTasks(agentUser);

            if (agentTaskIds.isEmpty()) {
                // 如果没有找到待办任务，返回错误响应
                return new ResponseEntity<>(new BaseResponse<>(1, "No tasks found for user: " + agentUser, null), HttpStatus.BAD_REQUEST);
            }

            // 遍历任务 ID 列表并完成每个任务
            for (String taskId : agentTaskIds) {
                taskService.complete(taskId);
            }

            // 返回成功的响应
            return new ResponseEntity<>(new BaseResponse<>(0, "Success", null), HttpStatus.OK);
        } catch (Exception e) {
            // 捕获异常并返回错误响应
            e.printStackTrace();
            return new ResponseEntity<>(new BaseResponse<>(1, "Failed: " + e.getMessage(), null), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

//    /**
//     * 查询指定用户的历史绩效.
//     *
//     * @param userId 用户id
//     * @return 历史流程集合
//     */
//    @PostMapping("/history-process-def/userId/{userId}")
//    public ResponseEntity<Object> getHistoryProcessDef(@PathVariable Long userId) {
//        //1.根据用户id查询历史流程
//        List<HistoricVariableInstance> historicVariableInstanceList = historyService
//                .createHistoricVariableInstanceQuery()
//                .variableValueEquals("ownerId", userId)
//                .list();
//        //2.抽出流程插入ID
//        Set<String> processInstanceIds = historicVariableInstanceList.stream()
//                .map(HistoricVariableInstance::getProcessInstanceId)
//                .collect(Collectors.toSet());
//        //3.根据流程插入ID查询历史流程
//        List<HistoricProcessInstance> historicProcessInstanceList = historyService
//                .createHistoricProcessInstanceQuery()
//                .processInstanceIds(processInstanceIds)
//                .list();
//        //4.抽出流程定义ID集合
//        Set<String> processDefinitionIds = historicProcessInstanceList.stream()
//                .map(HistoricProcessInstance::getProcessDefinitionId)
//                .collect(Collectors.toSet());
//        //5.根据流程定义ID获取流程定义
//        List<ProcessDefinition> processDefinitionList = repositoryService
//                .createProcessDefinitionQuery()
//                .processDefinitionIds(processDefinitionIds)
//                .list();
//        //6.抽出流程部署id
//        Set<String> deploymentIds = processDefinitionList.stream()
//                .map(ProcessDefinition::getDeploymentId)
//                .collect(Collectors.toSet());
//        //7.返回流程部署id
//        return new ResponseEntity<>(BaseResponse.success(deploymentIds), HttpStatus.OK);
//    }

    /**
     * 查询指定用户的历史绩效.
     *
     * @param userId 用户id
     * @return 历史流程集合
     */
    @PostMapping("/history-process-def/userId/{userId}")
    public ResponseEntity<Object> getHistoryProcessDef(@PathVariable Long userId) {
        // 1. 根据用户id查询历史流程变量实例，获取该用户作为负责人启动的所有流程相关变量
        List<HistoricVariableInstance> historicVariableInstanceList = historyService
                .createHistoricVariableInstanceQuery() // 创建历史变量实例查询对象
                .variableValueEquals("ownerId", userId.intValue()) // 筛选变量名为"ownerId"且值等于传入userId的历史变量实例
                .list(); // 执行查询并返回结果列表

        // 2. 从历史流程变量实例中抽出流程实例ID，用于后续查询具体的历史流程实例
        Set<String> processInstanceIds = historicVariableInstanceList.stream() // 将历史变量实例列表转换为流
                .map(HistoricVariableInstance::getProcessInstanceId) // 提取每个历史变量实例对应的流程实例ID
                .collect(Collectors.toSet()); // 将提取的流程实例ID收集到集合中，去重

        // 3. 根据流程实例ID查询历史流程实例，获取用户参与的具体流程实例信息
        List<HistoricProcessInstance> historicProcessInstanceList = historyService
                .createHistoricProcessInstanceQuery() // 创建历史流程实例查询对象
                .processInstanceIds(processInstanceIds) // 设置要查询的流程实例ID集合
                .list(); // 执行查询并返回结果列表

        // 4. 将历史流程实例转为Map，键为流程定义id，值为流程实例id，处理重复键的情况
        Map<String, String> processInstanceIdMap = new HashMap<>(); // 创建Map存储流程定义id和流程实例id的映射
        Map<String, List<String>> duplicateKeys = new HashMap<>(); // 创建Map记录重复的流程定义id对应的流程实例id列表

        historicProcessInstanceList.forEach(item -> { // 遍历历史流程实例列表
            String key = item.getProcessDefinitionId(); // 获取流程定义id作为键
            String value = item.getId(); // 获取流程实例id作为值
            if (processInstanceIdMap.containsKey(key)) { // 如果Map中已存在该流程定义id
                duplicateKeys.computeIfAbsent(key, k -> new ArrayList<>()).add(value); // 将对应的流程实例id添加到重复键记录Map中
            } else {
                processInstanceIdMap.put(key, value); // 否则，将流程定义id和流程实例id的映射添加到Map中
            }
        });

        // 打印重复键信息
        System.out.println("Duplicate keys: " + duplicateKeys);

        // 5. 从历史流程实例中抽出流程定义ID集合，用于查询对应的流程定义信息
        Set<String> processDefinitionIds = historicProcessInstanceList.stream() // 将历史流程实例列表转换为流
                .map(HistoricProcessInstance::getProcessDefinitionId) // 提取每个历史流程实例对应的流程定义ID
                .collect(Collectors.toSet()); // 将提取的流程定义ID收集到集合中，去重

        // 6. 根据流程定义ID获取流程定义，获取流程的相关定义信息，如流程名称、流程部署id等
        List<ProcessDefinition> processDefinitionList = repositoryService
                .createProcessDefinitionQuery() // 创建流程定义查询对象
                .processDefinitionIds(processDefinitionIds) // 设置要查询的流程定义ID集合
                .list(); // 执行查询并返回结果列表

        // 7. 从流程定义中抽出流程部署id集合，用于查询流程部署信息
        List<String> deploymentIds = processDefinitionList.stream() // 将流程定义列表转换为流
                .map(ProcessDefinition::getDeploymentId) // 提取每个流程定义对应的部署ID
                .collect(Collectors.toList()); // 将提取的部署ID收集到列表中

        // 8. 将流程定义转为map，键为流程部署id，值为流程定义id，方便后续根据部署id获取流程定义id
        Map<String, String> deploymentIdMap = processDefinitionList
                .stream() // 将流程定义列表转换为流
                .collect(Collectors.toMap( // 收集流中的元素到Map
                        ProcessDefinition::getDeploymentId, // Map的键为流程部署ID
                        ProcessDefinition::getId)); // Map的值为流程定义ID

        // 9. 查询流程部署信息，获取流程部署时的相关信息，如部署名称等
        List<Deployment> deploymentList = repositoryService
                .createDeploymentQuery() // 创建流程部署查询对象
                .deploymentIds(deploymentIds) // 设置要查询的流程部署ID集合
                .list(); // 执行查询并返回结果列表

        // 10. 声明结果集，用于存储最终要返回的历史绩效信息
        List<HistoryPerformanceVo> historyPerformanceVos = new ArrayList<>();

        // 11. 遍历流程部署集合，为返回对象赋值
        deploymentList.forEach(deployment -> {
            // 11-1. 声明历史流程对象，用于封装单个历史绩效信息
            HistoryPerformanceVo historyPerformanceVo = new HistoryPerformanceVo();

            // 11-2. 设置绩效名称为流程部署名称，假设部署名称代表绩效名称
            historyPerformanceVo.setPerformanceName(deployment.getName());

            // 11-3. 设置绩效分数：先根据部署id获取流程定义id，再根据流程定义id获取流程实例id，最后根据流程实例id查询该流程实例的历史变量实例中的分数
            String processDefinitionId = deploymentIdMap.get(deployment.getId()); // 根据部署ID获取流程定义ID
            String processInstanceId = processInstanceIdMap.get(processDefinitionId); // 根据流程定义ID获取流程实例ID
            List<HistoricVariableInstance> historicVariableInstances = historyService
                    .createHistoricVariableInstanceQuery() // 创建历史变量实例查询对象
                    .processInstanceId(processInstanceId) // 设置要查询的流程实例ID
                    .list(); // 执行查询并返回结果列表
            List<HistoricVariableInstance> scoreList = historicVariableInstances.stream() // 将历史变量实例列表转换为流
                    .filter(historicVariableInstance -> "score".equals(historicVariableInstance.getVariableName())) // 筛选变量名为"score"的历史变量实例
                    .toList(); // 将筛选结果转换为列表

            // 检查分数变量是否存在，并正确处理其类型
            if (!scoreList.isEmpty()) { // 如果存在分数变量
                Object scoreValue = scoreList.get(0).getValue(); // 获取分数值
                if (scoreValue != null) { // 如果分数值不为空
                    if (scoreValue instanceof String) { // 如果分数值是String类型
                        historyPerformanceVo.setScore((String) scoreValue); // 直接设置分数
                    } else if (scoreValue instanceof Integer) { // 如果分数值是Integer类型
                        historyPerformanceVo.setScore(scoreValue.toString()); // 将Integer转换为String后设置分数
                    } else {
                        // 如果分数值是其他类型，转换为String后设置分数
                        historyPerformanceVo.setScore(scoreValue.toString());
                    }
                } else {
                    historyPerformanceVo.setScore(null); // 如果分数值为空，设置分数为null
                }
            } else {
                historyPerformanceVo.setScore(null); // 如果没有分数变量，设置分数为null
            }

            // 11-4. 将封装好的历史绩效对象添加进集合
            historyPerformanceVos.add(historyPerformanceVo);
        });

        // 12. 返回流程绩效对象集合作为响应结果
        return new ResponseEntity<>(BaseResponse.success(historyPerformanceVos), HttpStatus.OK);
    }



    @PostMapping("/rollback/targetTaskId/{targetTaskId}")
    public ResponseEntity<Object> rollBackTask(@PathVariable String targetTaskId) {
        // 1. 查询目标任务数据
        HistoricTaskInstance targetTask = historyService
                .createHistoricTaskInstanceQuery()
                .taskId(targetTaskId)
                .singleResult();
        // 2. 判空
        if (targetTask == null) {
            return new ResponseEntity<>(BaseResponse.success("驳回目的任务不存在！"), null,
                    HttpStatus.BAD_REQUEST);
        }
        // 3. 获取流程实例id
        String processInstanceId = targetTask.getProcessInstanceId();
        // 4. 获取当前任务节点
        Task sourceTask = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .active()
                .singleResult();
        // 5. 判空
        if (sourceTask == null) {
            return new ResponseEntity<>(BaseResponse.success("驳回当前任务不存在！"), null,
                    HttpStatus.BAD_REQUEST);
        }
        // 6. 不能驳回到自己
        if (targetTask.equals(sourceTask)) {
            return new ResponseEntity<>(BaseResponse.success("不能驳回到当前节点！"), null,
                    HttpStatus.BAD_REQUEST);
        }
        // 7. 获取流程定义id
        String processDefinitionId = targetTask.getProcessDefinitionId();
        // 8. 使用流程定义id查询流程定义，获取流程定义的所有节点信息
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        Process process = bpmnModel.getProcesses().get(0);
        Collection<FlowElement> flowElements = process.getFlowElements();
        // 9. 遍历流程定义的所有节点，找到目标节点的定义信息
        FlowElement targetElement = null;
        for (FlowElement flowElement : flowElements) {
            if (flowElement.getId().equals(targetTask.getTaskDefinitionKey())) {
                targetElement = flowElement;
                break;
            }
        }
        // 10. 判空
        if (targetElement == null) {
            return new ResponseEntity<>(BaseResponse.success("驳回目的任务定义不存在！"), null,
                    HttpStatus.BAD_REQUEST);
        }

        // 在这里继续实现其他逻辑，比如执行回退操作等
        return new ResponseEntity<>(BaseResponse.success("回退操作成功"), HttpStatus.OK);
    }



    /**
     * 查询指定用户的待办任务 ID 列表。
     * <p>
     * 该方法使用 Flowable 的 TaskService 查询指定用户的待办任务。待办任务是指分配给该用户的、
     * 尚未完成的任务。这些任务可能处于流程的不同步骤中，等待用户的操作。
     *
     * @param user 用户名，用于查询分配给该用户的任务
     * @return 返回待办任务 ID 列表
     */
    private List<String> findUserAgentTasks(String user) {
        // 使用 TaskService 创建任务查询。TaskService 是 Flowable 引擎中用于管理任务的服务
        List<Task> tasks = taskService.createTaskQuery()
                // 指定任务分配给的用户。taskAssignee 是 Flowable 中用于标识任务分配对象的属性
                .taskAssignee(user)
                // 执行查询并获取任务列表
                .list();

        if (tasks.isEmpty()) {
            // 如果没有任务，返回空列表
            return Collections.emptyList();
        }

        // 提取任务 ID 列表。任务 ID 是 Flowable 引擎中唯一标识任务的字符串
        return tasks.stream().map(Task::getId).collect(Collectors.toList());
    }

    /**
     * 查询流程的待办任务.
     *
     * @param procDefId 流程定义ID
     * @return 待办任务id
     */
    private String findUserAgentTask(String procDefId) {
        //1.查询流程的待办任务
        Task agentTask = taskService.createTaskQuery()
                .processDefinitionId(procDefId)
                .singleResult();
        //2.返回待办任务的id
        return agentTask.getId();
    }

    /**
     * 回退节点并清理数据.
     *
     * @param sourceTask 当前任务
     * @param targetTask 目标任务
     * @return 驳回后的任务
     */
    public Task rollbackTask(Task sourceTask, HistoricTaskInstance targetTask) {
        //1.获取流程实例id
        String processInstanceId = sourceTask.getProcessInstanceId();
        //2.回退节点
        runtimeService.createChangeActivityStateBuilder()
                //指定流程实例ID
                .processInstanceId(processInstanceId)
                //指定源节点和目标节点
                .moveActivityIdTo(sourceTask.getTaskDefinitionKey(), targetTask.getTaskDefinitionKey())
                .changeState();
        //3.清理两个节点之间的脏数据
        clearDirtyData(processInstanceId, sourceTask, targetTask);
        //4.返回新目标节点
        return taskService.createTaskQuery()
                //指定流程实例ID
                .processInstanceId(processInstanceId)
                //指定目标节点定义
                .taskDefinitionKey(targetTask.getTaskDefinitionKey())
                .singleResult();
    }

    /**
     * 清除节点脏数据.
     *
     * @param processInstanceId 流程实例id
     * @param sourceTask      当前任务id
     * @param targetTask      目标任务id
     */
    private void clearDirtyData(String processInstanceId, Task sourceTask,
                                HistoricTaskInstance targetTask) {
        //1.获取历史任务列表
        List<HistoricTaskInstance> historyTasks = historyService
                .createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId)
                //按照任务开始时间降序排序
                .orderByHistoricTaskInstanceStartTime().desc()
                .list();
        //2.获取sourceTaskId和targetTaskId之间的所有任务节点，包括 targetTask 和 sourceTask，回滚之后删除。
        List<HistoricTaskInstance> betweenNodes =
                getBetweenNodes(historyTasks, sourceTask.getId(), targetTask.getId());
        //3.获取节点id列表
        List<String> taskIds = betweenNodes.stream()
                .map(HistoricTaskInstance::getId)
                .toList();
        //4.删除流程变量
        List<String> variableKeys = new ArrayList<>();
        for (String taskId : taskIds) {
            //分数key
            String scoreKey = "score";
            //所属人key
            String ownerKey = "ownerId";
            variableKeys.add(scoreKey);
            variableKeys.add(ownerKey);
            //删除历史节点
            historyService.deleteHistoricTaskInstance(taskId);
        }
        //5.删除流程实例中的指定变量
        runtimeService.removeVariables(processInstanceId, variableKeys);
    }

    /**
     * 获取sourceTaskId和targetTaskId之间的所有任务节点,包括 targetTask 和 sourceTask.
     *
     * @param sourceTaskId 当前任务id
     * @param targetTaskId 目标任务id
     * @return 任务节点列表
     */
    List<HistoricTaskInstance> getBetweenNodes(List<HistoricTaskInstance> historicTasks,
                                               String sourceTaskId,
                                               String targetTaskId) {
        //1.初始化一个列表，用于存储源任务和目标任务之间的所有任务节点
        List<HistoricTaskInstance> betweenNodes = new ArrayList<>();
        //2.定义一个标志，用于判断是否开始记录任务节点
        boolean startRecord = false;
        for (HistoricTaskInstance historicTask : historicTasks) {
            //3.如果历史任务的ID等于源任务的ID，那么开始记录任务节点
            if (Objects.equals(historicTask.getId(), sourceTaskId)) {
                startRecord = true;
            }
            //4.如果开始记录任务节点，那么将当前历史任务添加到任务节点列表中
            if (startRecord) {
                betweenNodes.add(historicTask);
            }
            //5.如果历史任务的ID等于目标任务的ID，那么停止记录任务节点，并结束循环
            if (Objects.equals(historicTask.getId(), targetTaskId)) {
                break;
            }
        }
        //6.返回任务节点列表
        return betweenNodes;
    }






//    @PostMapping("/deploy")
//    public ResponseEntity<Object> createProcessDef() {
//        try {
//            // 创建新的部署对象。部署是将 BPMN 文件等资源部署到 Flowable 引擎的过程
//            Deployment deployment = repositoryService.createDeployment()
//                    // 从类路径加载 BPMN 文件。这里 BPMN 文件位于 resources/process 目录下
//                    .addClasspathResource("process/admin.bpmn20.xml")
//                    // 设置部署名称，用于在 Flowable 引擎中标识这个部署
//                    .name("绩效流程")
//                    // 执行部署操作
//                    .deploy();
//
//            // 返回成功的响应，包含部署 ID
//            return new ResponseEntity<>(new BaseResponse<>(0, "Success", deployment.getId()), HttpStatus.OK);
//        } catch (Exception e) {
//            // 捕获异常并返回错误响应
//            e.printStackTrace();
//            return new ResponseEntity<>(new BaseResponse<>(1, "Failed: " + e.getMessage(), null), HttpStatus.INTERNAL_SERVER_ERROR);
//        }
//    }
//
//
//    @PostMapping("/deploy1")
//    public ResponseEntity<Object> createProcessDef1() {
//        //1,创建部署对象
//        Deployment deployment = repositoryService.createDeployment()
//                //2.添加流程定义文件
//                .addClasspathResource("process/admin.bpmn20.xml")
//                //3.设置流程名称
//                .name("绩效流程")
//                //4.部署
//                .deploy();
//        //2.通过流程部署id查询流程定义id
//        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
//                .deploymentId(deployment.getId()).singleResult();
//        //3.返回流程定义id
//        return new ResponseEntity<>(BaseResponse.success(processDefinition.getId()), HttpStatus.OK);
//    }
}


